package com.ruoyi.web.controller.work;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.poi.MapExcelUtil;
import com.ruoyi.work.domain.WorkProject;
import com.ruoyi.work.domain.vo.*;
import com.ruoyi.work.service.IWorkReportService;
import com.ruoyi.work.service.impl.UserHortExportServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: MMDZ
 * @Desc: TODO 统计报表
 */
@RestController
@RequestMapping("/work/report")
public class WorkReportController extends BaseController {

    @Autowired
    private IWorkReportService workReportService;
    @Autowired
    private UserHortExportServiceImpl userHortExportService;

    /**
     * 人员工时清单
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:uhour')")
    @PostMapping("/uhour")
    public AjaxResult uhour(@RequestBody UserHourReport report) {
        Integer pageNum = (Integer) report.getParams().get("pageNum");
        Integer pageSize = (Integer) report.getParams().get("pageSize");
        if(Objects.isNull(pageNum) || Objects.isNull(pageSize))
            throw new ServiceException("分页参数异常，请联系管理员！", 303);
        return AjaxResult.success(workReportService.selectUserHourList(report, pageNum, pageSize, false));
    }

    /**
     * 人员工时清单 导出
     */
    @PreAuthorize("@ss.hasPermi('work:report:uhour')")
    @Log(title = "人员工时清单", businessType = BusinessType.EXPORT)
    @PostMapping("/uhourexport")
    public void uexport(HttpServletResponse response, UserHourReport report) {
        userHortExportService.export(response, report);
    }

    /**
     * 项目工时清单
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:phour')")
    @GetMapping("/phour")
    public AjaxResult phour(ProjectHourReport report) {
        List<ProjectHourReport> reports = workReportService.selectProjectHourList(report);
        return AjaxResult.success(reports);
    }

    /**
     * 导出项目工时清单
     */
    @PreAuthorize("@ss.hasPermi('work:report:phour')")
    @Log(title = "项目工时清单", businessType = BusinessType.EXPORT)
    @PostMapping("/phourexport")
    public void pexport(HttpServletResponse response, ProjectHourReport report) {
        List<String> heads = new ArrayList<>();// 标题
        List<String> tempHeads = new ArrayList<>();// 数据 key
        List<String> stages = report.getStages();// 阶段
        List<ProjectHourReport> list = workReportService.selectProjectHourList(report);// 数据

        // 标题数据
        List<String> head = Stream.of("部门", "姓名", "工号", "岗位性质", "阶段合计(H)").collect(Collectors.toList());
        List<String> tempHead = Stream.of("deptName", "nickName", "userName", "postName", "sum").collect(Collectors.toList());
        // 添加标题数据 key
        tempHeads.addAll(tempHead);
        tempHeads.addAll(stages);
        // 添加标题
        heads.addAll(head);
        heads.addAll(stages);

        // 添加数据，转换格式
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("deptName", list.get(i).getDeptName());//部门
            dataMap.put("nickName", list.get(i).getNickName());//姓名
            dataMap.put("userName", list.get(i).getUserName());//工号
            dataMap.put("postName", list.get(i).getPostName());//岗位性质
            dataMap.put("sum", list.get(i).getSum());//阶段合计
            List<Map<String, Double>> stageList = list.get(i).getStage();//动态阶段
            stageList.forEach(map -> dataMap.putAll(map));
            dataMapList.add(dataMap);
        }

        MapExcelUtil.exportExcel(response, heads, tempHeads, dataMapList, "项目工时清单信息数据");
    }

    /**
     * 人力成本明细
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:detailcost')")
    @GetMapping("/detailcost")
    public AjaxResult detailcost(CostDetailReport report) {
        Integer pageNum = ServletUtils.getParameterToInt(TableSupport.PAGE_NUM);
        Integer pageSize = ServletUtils.getParameterToInt(TableSupport.PAGE_SIZE);
        return AjaxResult.success(workReportService.selectDetailCostList(pageNum, pageSize, report, false));
    }

    /**
     * 导出人力成本明细
     */
    @PreAuthorize("@ss.hasPermi('work:report:detailcost')")
    @Log(title = "人力成本明细", businessType = BusinessType.EXPORT)
    @PostMapping("/detailcostexport")
    public void detailcostexport(HttpServletResponse response, CostDetailReport report) {
        List<String> heads = new ArrayList<>();// 标题
        List<String> tempHeads = new ArrayList<>();// 数据 key
        List<String> stages = workReportService.selectWorkStageAll();// 阶段
        Map resMap = workReportService.selectDetailCostList(1, 10, report, true);
        List<CostDetailReport> list = (List<CostDetailReport>) resMap.get("data");

        // 标题数据
        List<String> head = Stream.of("项目代码", "部门", "姓名", "工号", "岗位", "日期", "合计(H)").collect(Collectors.toList());
        List<String> tempHead = Stream.of("projectCode", "deptName", "nickName", "userName", "postName", "strDate", "sumHour").collect(Collectors.toList());
        // 添加标题数据 key
        tempHeads.addAll(tempHead);
        tempHeads.addAll(stages);
        // 添加标题
        heads.addAll(head);
        heads.addAll(stages);

        // 添加数据，转换格式
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("projectCode", list.get(i).getProjectCode());//项目代码
            dataMap.put("deptName", list.get(i).getDeptName());//部门
            dataMap.put("nickName", list.get(i).getNickName());//姓名
            dataMap.put("userName", list.get(i).getUserName());//工号
            dataMap.put("postName", list.get(i).getPostName());//岗位
            dataMap.put("strDate", list.get(i).getStrDate());//日期
            dataMap.put("sumHour", list.get(i).getSumHour());//合计
            List<Map<String, Double>> stageList = list.get(i).getStage();//动态阶段
            stageList.forEach(map -> dataMap.putAll(map));
            dataMapList.add(dataMap);
        }

        MapExcelUtil.exportExcel(response, heads, tempHeads, dataMapList, "人力成本明细信息数据");
    }

    /**
     * 人力成本总汇
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:sumcost')")
    @GetMapping("/sumcost")
    public AjaxResult sumcost(CostCollectionReport report) {
        Integer pageNum = ServletUtils.getParameterToInt(TableSupport.PAGE_NUM);
        Integer pageSize = ServletUtils.getParameterToInt(TableSupport.PAGE_SIZE);
        return AjaxResult.success(workReportService.selectCostCollectionList(pageNum, pageSize, report, false));
    }

    /**
     * 导出人力成本总汇
     */
    @PreAuthorize("@ss.hasPermi('work:report:sumcost')")
    @Log(title = "人力成本总汇", businessType = BusinessType.EXPORT)
    @PostMapping("/sumcostexport")
    public void detailcostexport(HttpServletResponse response, CostCollectionReport report) {
        List<String> heads = new ArrayList<>();// 标题
        List<String> tempHeads = new ArrayList<>();// 数据 key
        Map resMap = workReportService.selectCostCollectionList(1, 10, report, true);
        List<CostCollectionReport> list = (List<CostCollectionReport>) resMap.get("data");
        List<String> stageNameList = (List<String>) resMap.get("headers1");
        List<String> stageCostList = (List<String>) resMap.get("headers2");

        // 标题数据
        List<String> head = Stream.of("项目代码", "部门", "姓名", "工号", "岗位", "合计工时(H)", "时薪(元)","成本合计(元)").collect(Collectors.toList());
        List<String> tempHead = Stream.of("projectCode", "deptName", "nickName", "userName", "postName", "sumHour", "hourPay", "sumCost").collect(Collectors.toList());
        // 添加标题数据 key
        tempHeads.addAll(tempHead);
        tempHeads.addAll(stageNameList);
        tempHeads.addAll(stageCostList);
        // 添加标题
        heads.addAll(head);
        heads.addAll(stageNameList);
        heads.addAll(stageCostList);

        // 添加数据，转换格式
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("projectCode", list.get(i).getProjectCode());//项目代码
            dataMap.put("deptName", list.get(i).getDeptName());//部门
            dataMap.put("nickName", list.get(i).getNickName());//姓名
            dataMap.put("userName", list.get(i).getUserName());//工号
            dataMap.put("postName", list.get(i).getPostName());//岗位
            dataMap.put("sumHour", list.get(i).getSumHour());//合计工时
            dataMap.put("hourPay", list.get(i).getHourPay());//时薪
            dataMap.put("sumCost", list.get(i).getSumCost());//成本合计
            List<Map<String, Double>> stageList = list.get(i).getStageHour();//动态阶段
            stageList.forEach(map -> dataMap.putAll(map));
            List<Map<String, Double>> costList = list.get(i).getStageCost();//动态阶段
            costList.forEach(map -> dataMap.putAll(map));
            dataMapList.add(dataMap);
        }

        MapExcelUtil.exportExcel(response, heads, tempHeads, dataMapList, "人力成本总汇信息数据");
    }

    /**
     * 人力成本统计表(部门维度) 以审核通过 为有效工时
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:dcost')")
    @PostMapping("/dcost")
    public TableDataInfo dcost(@RequestBody DeptCostReport report) {
        Integer pageNum = (Integer) report.getParams().get("pageNum");
        Integer pageSize = (Integer) report.getParams().get("pageSize");
        if(Objects.isNull(pageNum) || Objects.isNull(pageSize))
            throw new ServiceException("分页参数异常，请联系管理员！", 303);
        PageUtils.startPage(pageNum, pageSize);
        List<DeptCostReport> reports = workReportService.selectDeptCostList(report);
        return PageUtils.getDataTable(reports);
    }

    /**
     * 导出人力成本(部门维度)
     */
    @PreAuthorize("@ss.hasPermi('work:report:dcost')")
    @Log(title = "导出人力成本(部门维度)", businessType = BusinessType.EXPORT)
    @PostMapping("/dcostexport")
    public void dexport(HttpServletResponse response, DeptCostReport report) {
        List<String> heads = new ArrayList<>();// 标题
        List<String> tempHeads = new ArrayList<>();// 数据 key
        List<DeptCostReport> list = workReportService.selectDeptCostList(report);// 数据

        // 标题数据
        List<WorkProject> projects = workReportService.selectFillProjectAll();
        List<String> projectCodes = projects.stream().map(a -> a.getProjectCode()).sorted().collect(Collectors.toList());// 排序
        List<String> head = Stream.of("部门", "工号", "人员姓名", "职级职等", "金额合计(元)", "工时合计(H)").collect(Collectors.toList());
        List<String> tempHead = Stream.of("deptName", "userName", "nickName", "level", "amount", "sumHour").collect(Collectors.toList());
        // 添加标题数据 key
        tempHeads.addAll(tempHead);
        tempHeads.addAll(projectCodes);
        // 添加标题
        heads.addAll(head);
        heads.addAll(projectCodes);

        // 添加数据，转换格式
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("deptName", list.get(i).getDeptName());//部门
            dataMap.put("userName", list.get(i).getUserName());//工号
            dataMap.put("nickName", list.get(i).getNickName());//人员姓名
            dataMap.put("level", list.get(i).getLevel());//职级职等
            dataMap.put("amount", list.get(i).getAmount());//金额合计
            dataMap.put("sumHour", list.get(i).getSumHour());//工时合计
            List<Map<String, Double>> projectCost = list.get(i).getProjectCost();//人力成本费用
            projectCost.forEach(map -> dataMap.putAll(map));
            dataMapList.add(dataMap);
        }

        MapExcelUtil.exportExcel(response, heads, tempHeads, dataMapList, "部门人力成本信息数据");
    }

    /**
     * 人力成本(项目维度) 以审核通过 为有效工时
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:pcost')")
    @GetMapping("/pcost")
    public TableDataInfo pcost(ProjectCostReport report) {
        startPage();
        List<ProjectCostReport> reports = workReportService.selectProjectCostList(report);
        return getDataTable(reports);
    }

    /**
     * 导出人力成本(项目维度)
     */
    @PreAuthorize("@ss.hasPermi('work:report:pcost')")
    @Log(title = "导出人力成本(项目维度)", businessType = BusinessType.EXPORT)
    @PostMapping("/pcostexport")
    public void pexport(HttpServletResponse response, ProjectCostReport report) {
        List<ProjectCostReport> list = workReportService.selectProjectCostList(report);
        ExcelUtil<ProjectCostReport> util = new ExcelUtil<ProjectCostReport>(ProjectCostReport.class);
        util.exportExcel(response, list, "项目人力成本信息数据");
    }

    /**
     * 项目 人力成本 核算
     *
     * @param report
     * @return
     */
    @PreAuthorize("@ss.hasPermi('work:report:pcheck')")
    @GetMapping("/pcheck")
    public TableDataInfo pcheck(ProjectCheckReport report) {
        startPage();
        List<ProjectCheckReport> reports = workReportService.selectProjectCheckList(report);
        return getDataTable(reports);
    }

    /**
     * 导出 项目 人力成本 核算
     */
    @PreAuthorize("@ss.hasPermi('work:report:pcheck')")
    @Log(title = "导出人力成本(项目核算)", businessType = BusinessType.EXPORT)
    @PostMapping("/pcheckexport")
    public void pcheckexport(HttpServletResponse response, ProjectCheckReport report) {
        List<ProjectCheckReport> list = workReportService.selectProjectCheckList(report);
        ExcelUtil<ProjectCheckReport> util = new ExcelUtil<ProjectCheckReport>(ProjectCheckReport.class);
        util.exportExcel(response, list, "项目人力成本核算信息数据");
    }

    /**
     * 获取已填写的项目
     *
     * @return
     */
    @GetMapping("/optionselect")
    public AjaxResult optionselect() {
        List<WorkProject> projects = workReportService.selectFillProjectAll();
        return AjaxResult.success(projects);
    }
}
